package com.chart.web.controller.system;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.chart.chart.domian.req.UListReq;
import com.chart.common.annotation.Log;
import com.chart.common.core.controller.BaseController;
import com.chart.common.core.domain.AjaxResult;
import com.chart.common.core.domain.entity.SysDept;
import com.chart.common.core.domain.entity.SysRole;
import com.chart.common.core.domain.entity.SysUser;
import com.chart.common.core.domain.entity.UserCoinLog;
import com.chart.common.core.page.TableDataInfo;
import com.chart.common.core.redis.RedisCache;
import com.chart.common.enums.BusinessType;
import com.chart.common.exception.CustomAesException;
import com.chart.common.utils.SecurityUtils;
import com.chart.common.utils.StringUtils;
import com.chart.common.utils.poi.ExcelUtil;
import com.chart.system.service.*;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.ArrayUtils;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.apache.http.util.EntityUtils;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.*;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.multipart.MultipartFile;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
import static com.chart.common.utils.wechat.WeChatUtils.*;

/**
 * 用户信息
 *
 * @author chart
 */
@RestController
@RequestMapping("/system/user")
@Slf4j
public class SysUserController extends BaseController {


    @Autowired
    private ISysUserService userService;

    @Autowired
    private ISysRoleService roleService;

    @Autowired
    private ISysDeptService deptService;

    @Autowired
    private ISysPostService postService;
    @Autowired
    private IUserCoinLogsService userCoinLogsService;

    @Autowired
    SysUserRoleService sysUserRoleService;

    @Autowired
    private RedisCache redisCache;

    @Value("${wxpay.token}")
    private String TOKEN;



    /**
     * 获取用户列表
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/list")
    public TableDataInfo list(SysUser user) {
        IPage<SysUser> list = userService.selectUserList(startPage(), user);
        return getDataTable(list);
    }

    @Log(title = "用户管理", businessType = BusinessType.EXPORT)
    @PreAuthorize("@ss.hasPermi('system:user:export')")
    @PostMapping("/export")
    public void export(HttpServletResponse response, SysUser user) {
        List<SysUser> list = userService.selectUserList(startPage(), user).getRecords();
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        util.exportExcel(response, list, "用户数据");
    }

    @Log(title = "用户管理", businessType = BusinessType.IMPORT)
    @PreAuthorize("@ss.hasPermi('system:user:import')")
    @PostMapping("/importData")
    public AjaxResult importData(MultipartFile file, boolean updateSupport) throws Exception {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        List<SysUser> userList = util.importExcel(file.getInputStream());
        String operName = getUsername();
        String message = userService.importUser(userList, updateSupport, operName);
        return success(message);
    }

    @PostMapping("/importTemplate")
    public void importTemplate(HttpServletResponse response) {
        ExcelUtil<SysUser> util = new ExcelUtil<SysUser>(SysUser.class);
        util.importTemplateExcel(response, "用户数据");
    }

    /**
     * 根据用户编号获取详细信息
     */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @GetMapping(value = {"/", "/{userId}"})
    public AjaxResult getInfo(@PathVariable(value = "userId", required = false) Long userId) {
        userService.checkUserDataScope(userId);
        AjaxResult ajax = AjaxResult.success();
        List<SysRole> roles = roleService.selectRoleAll();
        ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        ajax.put("posts", postService.selectPostAll());
        if (StringUtils.isNotNull(userId)) {
            SysUser sysUser = userService.selectUserById(userId);
            ajax.put(AjaxResult.DATA_TAG, sysUser);
            ajax.put("postIds", postService.selectPostListByUserId(userId));
            ajax.put("roleIds", sysUser.getRoles().stream().map(SysRole::getRoleId).collect(Collectors.toList()));
        }
        return ajax;
    }

    /**
     * 新增用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:add')")
    @Log(title = "用户管理", businessType = BusinessType.INSERT)
    @PostMapping("/add")
    public AjaxResult add(@Validated @RequestBody SysUser user) {
        if (!userService.checkUserNameUnique(user)) {
            return error("新增用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
            return error("新增用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
            return error("新增用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setCreateBy(getUsername());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        return toAjax(userService.insertUser(user));
    }

    /**
     * 修改用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping
    public AjaxResult edit(@Validated @RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        if (!userService.checkUserNameUnique(user)) {
            return error("修改用户'" + user.getUserName() + "'失败，登录账号已存在");
        } else if (StringUtils.isNotEmpty(user.getPhonenumber()) && !userService.checkPhoneUnique(user)) {
            return error("修改用户'" + user.getUserName() + "'失败，手机号码已存在");
        } else if (StringUtils.isNotEmpty(user.getEmail()) && !userService.checkEmailUnique(user)) {
            return error("修改用户'" + user.getUserName() + "'失败，邮箱账号已存在");
        }
        user.setUpdateBy(getUsername());
        return toAjax(userService.updateUser(user));
    }

    /**
     * 删除用户
     */
    @PreAuthorize("@ss.hasPermi('system:user:remove')")
    @Log(title = "用户管理", businessType = BusinessType.DELETE)
    @DeleteMapping("/{userIds}")
    public AjaxResult remove(@PathVariable Long[] userIds) {
        if (ArrayUtils.contains(userIds, getUserId())) {
            return error("当前用户不能删除");
        }
        return toAjax(userService.deleteUserByIds(userIds));
    }

    /**
     * 重置密码
     */
    @PreAuthorize("@ss.hasPermi('system:user:resetPwd')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/resetPwd")
    public AjaxResult resetPwd(@RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        user.setPassword(SecurityUtils.encryptPassword(user.getPassword()));
        user.setUpdateBy(getUsername());
        return toAjax(userService.resetPwd(user));
    }

    /**
     * 状态修改
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.UPDATE)
    @PutMapping("/changeStatus")
    public AjaxResult changeStatus(@RequestBody SysUser user) {
        userService.checkUserAllowed(user);
        userService.checkUserDataScope(user.getUserId());
        user.setUpdateBy(getUsername());
        return toAjax(userService.updateUserStatus(user));
    }

    /**
     * 根据用户编号获取授权角色
     */
    @PreAuthorize("@ss.hasPermi('system:user:query')")
    @GetMapping("/authRole/{userId}")
    public AjaxResult authRole(@PathVariable("userId") Long userId) {
        AjaxResult ajax = AjaxResult.success();
        SysUser user = userService.selectUserById(userId);
        List<SysRole> roles = roleService.selectRolesByUserId(userId);
        ajax.put("user", user);
        ajax.put("roles", SysUser.isAdmin(userId) ? roles : roles.stream().filter(r -> !r.isAdmin()).collect(Collectors.toList()));
        return ajax;
    }

    /**
     * 用户授权角色
     */
    @PreAuthorize("@ss.hasPermi('system:user:edit')")
    @Log(title = "用户管理", businessType = BusinessType.GRANT)
    @PutMapping("/authRole")
    public AjaxResult insertAuthRole(Long userId, Long[] roleIds) {
        userService.checkUserDataScope(userId);
        userService.insertUserAuth(userId, roleIds);
        return success();
    }

    /**
     * 获取部门树列表
     */
    @PreAuthorize("@ss.hasPermi('system:user:list')")
    @GetMapping("/deptTree")
    public AjaxResult deptTree(SysDept dept) {
        return success(deptService.selectDeptTreeList(dept));
    }


    /**
     * 完善用户信息
     */
    @PostMapping("/edit")
    public AjaxResult edit1(@Validated @RequestBody SysUser user) {

        String otherKnowChannel = user.getOtherKnowChannel();
        Integer knowChannel = user.getKnowChannel();
        //如果id==16 取值 otherPost
        Long userId = SecurityUtils.getUserId();
        if (!SecurityUtils.isAdmin(userId)) {
            user.setFreeOper(3);
            user.setUserId(userId);
            Boolean result = userService.editUser(user);
            if (result) {
                SysUser sysUser = new SysUser();
                sysUser.setUserId(userId);
                sysUser.setHasComplete(1);
                sysUser.setKnowChannel(knowChannel);
                sysUser.setOtherKnowChannel(otherKnowChannel);
                userService.updateById(sysUser);
                return AjaxResult.success();
            }
        }
        return AjaxResult.success();
    }


    /**
     * 修改用户信息
     */
    @GetMapping("/updateUser")
    public AjaxResult update(Integer hasLoggedIn) {
        //如果id==16 取值 otherPost
        Long userId = SecurityUtils.getUserId();

        SysUser sysUser1 = userService.queryById(userId);
        Integer hasLoggedIn1 = sysUser1.getHasLoggedIn();
        Integer hasComplete = sysUser1.getHasComplete();
        if (hasLoggedIn1 == 0 || hasLoggedIn1.equals("") || hasLoggedIn1 == null) {
            //添加5个席位
            UserCoinLog userCoinLog = new UserCoinLog();
            userCoinLog.setUserId(userId);
            userCoinLog.setSeatCount(5);
            userCoinLog.setBehavior("SEATCOUNT");
            userCoinLogsService.save(userCoinLog);
        }

        SysUser sysUser = new SysUser();
        sysUser.setUserId(userId);
        sysUser.setHasLoggedIn(hasLoggedIn);
        userService.updateById(sysUser);


        return AjaxResult.success();
    }


    /**
     * 统计当前面用户总数
     *
     * @return
     */
    @GetMapping("/getTotalUserCount")
    public AjaxResult getTotalUserCount() {
        Long total = userService.getTotalUserCount();
        return AjaxResult.success(total);
    }

    /**
     * 获取每日新注册用户数
     */
    @GetMapping("/queryDailyNewUserCount")
    public AjaxResult getDailyNewUserCount() {
        Long total = userService.getDailyNewUserCount();
        return AjaxResult.success(total);
    }


    /**
     * 每日登录用户数（DAU）\(MAU)
     * 根据用户表
     */
    @GetMapping("/queryDailyAndMonthlyActiveUsers")
    public AjaxResult queryDailyAndMonthlyActiveUsers() {
        Long totalDau = userService.getDailyActiveUserCount();
        Long totalMau = userService.getMonthlyActiveUserCount();
        HashMap<String, Long> totalCount = new HashMap<>();
        totalCount.put("totalDau", totalDau);
        totalCount.put("totalMau", totalMau);
        return AjaxResult.success(totalCount);
    }


    /**
     * 每日登录用户数（DAU）\(MAU)
     * 根据记录表
     */
    @GetMapping("/queryDailyAndMonthlyActiveUserCoinLog")
    public AjaxResult queryDailyAndMonthlyActiveUserCoinLog() {


        //昨日登录用户数
        LocalDateTime startOfYesterday = LocalDate.now().minusDays(1).atStartOfDay();
        LocalDateTime endOfYesterday = LocalDate.now().minusDays(1).atTime(23, 59, 59, 999999999);
        LambdaQueryWrapper<UserCoinLog> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(UserCoinLog::getAction, "LOGINLOG");
        wrapper.le(UserCoinLog::getCreateTime, endOfYesterday); // 小于等于昨天的结束时间
        wrapper.ge(UserCoinLog::getCreateTime, startOfYesterday); // 大于等于昨天的开始时间
        // 查询昨天的登录记录
        List<UserCoinLog> listYesterday = userCoinLogsService.list(wrapper);
        int yesterdayLoginSize = listYesterday.size();


        //今日登录用户数
        LocalDateTime startOfDay = LocalDate.now().atStartOfDay();
        LocalDateTime endOfDay = LocalDate.now().atTime(23, 59, 59, 999999999);
        LambdaQueryWrapper<UserCoinLog> lqw = new LambdaQueryWrapper<>();
        lqw.eq(UserCoinLog::getAction, "LOGINLOG");
        lqw.le(UserCoinLog::getCreateTime, endOfDay);//小于等于
        lqw.ge(UserCoinLog::getCreateTime, startOfDay); //大于等于
        List<UserCoinLog> listDay = userCoinLogsService.list(lqw);
        int dayLogSize = listDay.size();


        // 本月登录用户数
        LocalDate today = LocalDate.now();
        LocalDate startOfMonth = today.withDayOfMonth(1);
        LocalDate lastDayOfMonth = today.withDayOfMonth(today.lengthOfMonth());
        LocalDateTime startOfMonthDateTime = startOfMonth.atStartOfDay();
        LocalDateTime endOfMonthDateTime = lastDayOfMonth.atTime(23, 59, 59, 999999999);
        LambdaQueryWrapper<UserCoinLog> monthlyWrapper = new LambdaQueryWrapper<>();
        monthlyWrapper.eq(UserCoinLog::getAction, "LOGINLOG");
        monthlyWrapper.ge(UserCoinLog::getCreateTime, startOfMonthDateTime);
        monthlyWrapper.le(UserCoinLog::getCreateTime, endOfMonthDateTime);
        List<UserCoinLog> listMonth = userCoinLogsService.list(monthlyWrapper);
        int monthLogSize = listMonth.size();

        //总用户数
        Long totalUserNumberLong = userService.getTotalUserCount();
        int totalUserNumber = totalUserNumberLong.intValue();


        UListReq req = new UListReq();
        req.setStartTime("");
        req.setEndTime("");

        // List<UserResp> list = userManager.getListBy(req);
        Integer registerTotal = userService.selectCount();

        //昨日新注册用户数
        LambdaQueryWrapper<SysUser> Wrapper = new LambdaQueryWrapper<>();
        Wrapper.le(SysUser::getCreateTime, endOfYesterday);
        Wrapper.ge(SysUser::getCreateTime, startOfYesterday);
        int registeredYesterday = userService.list(Wrapper).size();
        HashMap<String, Integer> totalCount = new HashMap<>();
        totalCount.put("yesterdayLoginSize", yesterdayLoginSize);
        totalCount.put("dayLogSize", dayLogSize);
        totalCount.put("monthLogSize", monthLogSize);
        totalCount.put("totalUserNumber", registerTotal);
        totalCount.put("registeredYesterday", registeredYesterday);
        return AjaxResult.success(totalCount);
    }


    /**
     * 删除用户
     *
     * @param userId
     * @return
     */

    @GetMapping("/delUser")
    public AjaxResult delUser(String userId) {
        if (userId == null) {
            return AjaxResult.error("用户ID不能为空");
        }
        long userIdAsLong = Long.parseLong(userId);
        userService.deleteUserById(userIdAsLong);
        userService.deleteUser(userIdAsLong);
        return AjaxResult.success();
    }


    /**
     * 微信公众平台的 GET 请求，用于验证 token
     *
     * @param signature
     * @param timestamp
     * @param nonce
     * @param echostr
     * @param response
     */
    @GetMapping("/event")
    public void verifyToken(@RequestParam String signature,
                            @RequestParam String timestamp,
                            @RequestParam String nonce,
                            @RequestParam String echostr,
                            HttpServletResponse response) {
        try {
            // 1. 将 token, timestamp, nonce 按字典序排序
            String[] arr = {TOKEN, timestamp, nonce};
            Arrays.sort(arr);

            // 2. 将三个参数拼接成字符串并进行 SHA1 加密
            StringBuilder content = new StringBuilder();
            for (String s : arr) {
                content.append(s);
            }
            String tempSignature = DigestUtils.sha1Hex(content.toString());

            // 3. 校验签名是否来自微信
            if (tempSignature.equals(signature)) {
                response.getWriter().write(echostr);  // 验证成功，返回 echostr
            } else {
                response.getWriter().write("fail");  // 验证失败
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 微信公众平台的 POST 请求，接收事件推送
     *
     * @param xmlData
     * @param response
     */
    @PostMapping("/event")
    public void handleWechatEvents(@RequestBody String xmlData, HttpServletResponse response) {
        // 非空校验
        if (xmlData == null || xmlData.isEmpty()) {
            logger.error("接收到微信的xmlData为空！");
            try {
                // 返回错误响应
                response.setStatus(HttpStatus.BAD_REQUEST.value());
                response.getWriter().write("xmlData不能为空");
            } catch (IOException e) {
                e.printStackTrace();
            }
            return;
        }
        try {
            System.out.println("微信官方回调了我的接口789");
            // 解析微信推送的XML数据
            Document document = DocumentHelper.parseText(xmlData);
            Element root = document.getRootElement();
            // 获取消息类型和事件类型
            String msgType = root.elementText("MsgType");
            String event = root.elementText("Event");
            String ticket = root.elementText("Ticket"); // 获取 Ticket
            System.out.println("我拿到了用户的ticket" + ticket);
            String openId = root.elementText("FromUserName");  // 提取用户的 OpenID
            if (StringUtils.isEmpty(openId)) {
                log.error("openId为空openId={}", openId);
            }
            // 处理事件推送
            if ("event".equals(msgType)) {
                if ("subscribe".equals(event)) {
                    // 处理用户首次关注公众号事件
                    String eventKey = root.elementText("EventKey");
                    if (eventKey != null && eventKey.startsWith("qrscene_")) {
                        // 提取场景值中的 userId
                        String userId = eventKey.replace("qrscene_", "");
                        System.out.println("用户通过二维码关注公众号，OpenID: " + openId + ", 用户ID: " + userId);
                        handleSubscribeEvent(openId, userId);

                        SysUser sysUser = userService.selectUserByOpenid(openId);
                        if (ObjectUtil.isEmpty(sysUser)) {
                            //数据库没有openid去验证
                            sendCustomWelcomeMessage(openId, ticket);
                        } else {

                            //有openid 加手机号 进入
                            // 调用方法处理欢迎逻辑   您好，首次微信登录，请先验证是否已完成注册
                            // 用户已存在，标记为已登录
                            redisCache.setCacheObject(ticket, "login_" + openId, 180, TimeUnit.SECONDS);  // 保存 ticket 和 openid

                            ScanMessage(openId);
                        }


                    } else {
                        System.out.println("用户直接关注了公众号，OpenID: " + openId);
                        handleSubscribeEvent(openId, null);  // 如果没有场景值，userId 为 null

                    }

                } else if ("unsubscribe".equals(event)) {
                    // 处理用户取消关注事件
                    System.out.println("用户取消关注公众号，OpenID: " + openId);
                    handleUnsubscribeEvent(openId);

                } else if ("SCAN".equals(event)) {

                    String eventKey = root.elementText("EventKey");
                    SysUser sysUser = userService.selectUserByOpenid(openId);
                    String phonenumber = sysUser != null ? sysUser.getPhonenumber() : null;

                    if (ObjectUtil.isEmpty(sysUser) || ObjectUtil.isEmpty(phonenumber)) {
                        // 用户不存在或电话号码为空时，不发送欢迎消息
                        if (ObjectUtil.isEmpty(sysUser)) {
                            System.out.println("用户不存在，不发送欢迎消息");
                            sendCustomWelcomeMessage(openId, ticket);
                        } else {
                            sendCustomWelcomeMessage(openId, ticket);
                            System.out.println("用户存在但电话号码为空，不发送欢迎消息");
                        }
                        // 其他处理逻辑
                        // 例如：记录日志、发送通知等
                    } else {
                        // 用户存在且电话号码不为空时的处理逻辑
                        System.out.println("用户存在且电话号码不为空，发送欢迎消息并保存 ticket 和 openid 的映射");
                        ScanMessage(openId);
                        //redisCache.setCacheObject(ticket, "login_" + openId, 180, TimeUnit.SECONDS);  // 保存 ticket 和 openid
                        redisCache.setCacheObject(ticket, "login_" + openId, 180, TimeUnit.SECONDS);  // 保存 ticket 和 openid


                    }


                    handleScanEvent(openId, eventKey);
                }
            }

            // 回复微信服务器，防止重试
            response.getWriter().write("success");

        } catch (Exception e) {
            e.printStackTrace();
            try {
                response.getWriter().write("fail");
            } catch (IOException ioException) {
                ioException.printStackTrace();
            }
        }
    }


    // 用户已关注消息的回复
    private void ScanMessage(String openId) {
        String[] messages = {
                "欢迎回家，又是元气满满的一天！",
                "欢迎回家，快来开启熟悉又全新的体验吧！",
                "欢迎回家，快来大显身手吧！",
                "老友回归，热忱依旧！",
                "欢迎回家，一同开启这熟悉又别具一格的精彩之行吧！"
        };

        Random random = new Random();
        int index = random.nextInt(messages.length); // 随机选择一个索引
        String ScanMessage = messages[index]; // 根据索引获取消息
        // 发送消息的逻辑（通过微信客服消息接口发送）
        sendTextMessageToUser(openId, ScanMessage);
        System.out.println("欢迎消息已发送给用户，OpenID: " + openId);

    }
    //统一发送信息接口
//    private void sendCustomWelcomeMessage(String openId) {
//
//            String    welcomeMessage = "您好，首次微信登录，请先验证是否已完成注册。" + "https://regbyh5.topcharts.cn" + "?openId=" + openId;
//
//
//            // 发送消息的逻辑（通过微信客服消息接口发送）
//            sendTextMessageToUser(openId, welcomeMessage);
//
//            System.out.println("欢迎消息已发送给用户，OpenID: " + openId);
//
//    }

    //    private void sendCustomWelcomeMessage(String openId) {
//        // 构建图文消息的数据结构
//        JSONObject article = new JSONObject();
//        article.put("title", "首次微信登录，请先验证");
//        article.put("description", "您好，首次微信登录，请先验证是否已完成注册。请点击这里进行验证：");
//        article.put("url", "https://regbyh5.topcharts.cn?openId=" + openId);
//        article.put("picurl", ""); // 可选，如果您希望消息中包含图片，可以设置这个字段
//
//        JSONObject news = new JSONObject();
//        news.put("articles", new JSONObject[] { article });
//
//        // 构建整个消息体
//        JSONObject message = new JSONObject();
//        message.put("touser", openId);
//        message.put("msgtype", "news");
//        message.put("news", news);
//
//        // 发送消息的逻辑（通过微信客服消息接口发送）
//        sendJsonMessageToUsers(message);
//
//        System.out.println("欢迎消息已发送给用户，OpenID: " + openId);
//    }
    private void sendCustomWelcomeMessage(String openId, String ticket) {
        // 构建图文消息的数据结构
        JSONObject article = new JSONObject();
        article.put("title", "首次微信登录，请先验证");
        article.put("description", "您好，首次微信登录，请先验证是否已完成注册。请点击这里进行验证：");
        article.put("url", "https://regbyh5.topcharts.cn/bind?openId=" + openId + "&ticket=" + ticket);
        article.put("picurl", "https://oss-shhz.oss-cn-shanghai.aliyuncs.com/%E5%85%AC%E4%BC%97%E5%8F%B7.png"); // 设置图片URL

        JSONObject news = new JSONObject();
        news.put("articles", new JSONObject[]{article});

        // 构建整个消息体
        JSONObject message = new JSONObject();
        message.put("touser", openId);
        message.put("msgtype", "news");
        message.put("news", news);

        // 发送消息的逻辑（通过微信客服消息接口发送）
        sendJsonMessageToUsers(message);

        System.out.println("欢迎消息已发送给用户，OpenID: " + openId);
    }

    private void sendJsonMessageToUsers(JSONObject message) {
        try {
            // 获取AccessToken
            String accessToken = getAccessTokenA();
            // 拼接URL
            String url = String.format(
                    "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s",
                    accessToken
            );
            // 构建JSON消息体
            String jsonPayload = message.toString();

            // 打印调试日志
            System.out.println("发送消息的URL：" + url);
            System.out.println("发送消息的内容：" + jsonPayload);

            // HTTP请求
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new StringEntity(jsonPayload, StandardCharsets.UTF_8));

            // 使用 Try-With-Resources 自动管理资源关闭
            try (CloseableHttpClient httpClient = HttpClients.createDefault();
                 CloseableHttpResponse response = httpClient.execute(httpPost)) {

                int statusCode = response.getStatusLine().getStatusCode();

                // 检查状态码
                if (statusCode == 200) {
                    System.out.println("消息发送成功！");
                } else {
                    System.err.println("消息发送失败，状态码：" + statusCode);
                    String responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                    System.err.println("响应内容：" + responseContent);
                }
            }
        } catch (CustomAesException e) {
            // 捕获自定义异常
            System.err.println("获取 AccessToken 时出错：" + e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            // 捕获 HTTP 请求相关异常
            System.err.println("发送 HTTP 请求时出错：" + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            // 捕获所有其他异常
            System.err.println("发送消息时发生未知错误：" + e.getMessage());
            e.printStackTrace();
        }
    }
//    private void sendJsonMessageToUsers(JSONObject message) {
//        try {
//            // 获取AccessToken
//            String accessToken = getAccessTokenA();
//            // 拼接URL
//            String url = String.format(
//                    "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s",
//                    accessToken
//            );
//            // 构建JSON消息体
//            String jsonPayload = message.toString();
//
//            // 打印调试日志
//            System.out.println("发送消息的URL：" + url);
//            System.out.println("发送消息的内容：" + jsonPayload);
//
//            // HTTP请求
//            HttpPost httpPost = new HttpPost(url);
//            httpPost.setEntity(new StringEntity(jsonPayload, StandardCharsets.UTF_8));
//
//            // 使用 Try-With-Resources 自动管理资源关闭
//            try (CloseableHttpClient httpClient = HttpClients.createDefault();
//                 CloseableHttpResponse response = httpClient.execute(httpPost)) {
//
//                int statusCode = response.getStatusLine().getStatusCode();
//
//                // 检查状态码
//                if (statusCode == 200) {
//                    System.out.println("消息发送成功！");
//                } else {
//                    System.err.println("消息发送失败，状态码：" + statusCode);
//                    String responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
//                    System.err.println("响应内容：" + responseContent);
//                }
//            }
//        } catch (CustomAesException e) {
//            // 捕获自定义异常
//            System.err.println("获取 AccessToken 时出错：" + e.getMessage());
//            e.printStackTrace();
//        } catch (IOException e) {
//            // 捕获 HTTP 请求相关异常
//            System.err.println("发送 HTTP 请求时出错：" + e.getMessage());
//            e.printStackTrace();
//        } catch (Exception e) {
//            // 捕获所有其他异常
//            System.err.println("发送消息时发生未知错误：" + e.getMessage());
//            e.printStackTrace();
//        }
//    }


    //统一消息发送接口
    private void sendTextMessageToUser(String openId, String content) {
        try {
            // 获取AccessToken
            String accessToken = getAccessTokenA();
            // 拼接URL
            String url = String.format(
                    "https://api.weixin.qq.com/cgi-bin/message/custom/send?access_token=%s",
                    accessToken
            );
            // 构建JSON消息体
            String jsonPayload = String.format(
                    "{\"touser\":\"%s\",\"msgtype\":\"text\",\"text\":{\"content\":\"%s\"}}",
                    openId, content
            );

            // 打印调试日志
            System.out.println("发送消息的URL：" + url);
            System.out.println("发送消息的内容：" + jsonPayload);

            // HTTP请求
            HttpPost httpPost = new HttpPost(url);
            httpPost.setEntity(new StringEntity(jsonPayload, ContentType.APPLICATION_JSON));

            // 使用 Try-With-Resources 自动管理资源关闭
            try (CloseableHttpClient httpClient = HttpClients.createDefault();
                 CloseableHttpResponse response = httpClient.execute(httpPost)) {

                int statusCode = response.getStatusLine().getStatusCode();

                // 检查状态码
                if (statusCode == 200) {
                    System.out.println("消息发送成功！");
                } else {
                    System.err.println("消息发送失败，状态码：" + statusCode);
                    String responseContent = EntityUtils.toString(response.getEntity(), StandardCharsets.UTF_8);
                    System.err.println("响应内容：" + responseContent);
                }
            }
        } catch (CustomAesException e) {
            // 捕获自定义异常
            System.err.println("获取 AccessToken 时出错：" + e.getMessage());
            e.printStackTrace();
        } catch (IOException e) {
            // 捕获 HTTP 请求相关异常
            System.err.println("发送 HTTP 请求时出错：" + e.getMessage());
            e.printStackTrace();
        } catch (Exception e) {
            // 捕获所有其他异常
            System.err.println("发送消息时发生未知错误：" + e.getMessage());
            e.printStackTrace();
        }
    }


    // 处理首次关注事件（附带二维码参数）
    private void handleSubscribeEvent(String openId, String userId) {
        if (userId != null) {
            // 处理通过带参数二维码关注的用户
            System.out.println("欢迎通过二维码关注的用户，OpenID: " + openId + ", 用户ID: " + userId);

            saveUserInfo(openId, userId);
        } else {
            // 处理直接关注的用户
            System.out.println("欢迎直接关注的用户，OpenID: " + openId);
            saveUserInfo(openId, null);  // 如果没有场景值，可以不保存 userId
        }

    }

    // 处理取消关注事件
    private void handleUnsubscribeEvent(String openId) {
        System.out.println("用户取消关注，OpenID: " + openId);
        // 在这里更新数据库，记录用户的取消关注行为
        updateUserStatus(openId, false);
    }

    // 处理已关注用户 扫描二维码事件
    private void handleScanEvent(String openId, String eventKey) {
        String userId = extractUserIdFromEventKey(eventKey);  // 提取用户ID
        System.out.println("已关注用户扫描二维码，OpenID: " + openId + ", 场景值: " + eventKey);
        System.out.println("已关注用户，场景值中提取的用户ID: " + userId);
        // 根据场景值和用户ID执行相应的业务逻辑
        saveScanEventInfo(openId, userId);

    }

    // 提取 userId 方法
    private String extractUserIdFromEventKey(String eventKey) {
        if (eventKey != null && !eventKey.isEmpty()) {
            try {
                // 尝试提取 userId (假设 eventKey 是数字形式的用户ID)
                return eventKey.replace("qrscene_", "");
            } catch (Exception e) {
                System.out.println("提取 userId 时发生错误: " + e.getMessage());
            }
        }
        return "未知用户ID";
    }

    // 模拟保存用户信息到数据库
    private void saveUserInfo(String openId, String userId) {
        // 在这里执行将 openId 和 userId 保存到数据库的操作
        System.out.println("保存用户信息到数据库，OpenID: " + openId + ", 用户ID: " + userId);
    }

    // 模拟更新用户状态（取消关注）
    private void updateUserStatus(String openId, boolean isActive) {
        // 在这里执行更新数据库中用户状态的操作
        System.out.println("更新用户状态为 " + (isActive ? "活跃" : "取消关注") + "，OpenID: " + openId);
    }

    // 保存二维码扫描事件的信息
    private void saveScanEventInfo(String openId, String userId) {
        // 在这里执行保存已关注用户扫描二维码后的事件信息的操作
        System.out.println("保存二维码扫描事件信息，OpenID: " + openId + ", 用户ID: " + userId);
    }


}
